package com.youkeyi.ddy.cloud.application.system.menu.controller;

import com.youkeyi.ddy.cloud.common.api.application.system.auth.dto.SystemAuthSimpleCloudDto;
import com.youkeyi.ddy.cloud.common.api.application.system.menu.SystemMenuCloudService;
import com.youkeyi.ddy.cloud.common.api.application.system.menu.dto.*;
import com.youkeyi.ddy.cloud.common.api.application.system.menu.param.*;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.PublicAuthCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.dto.PublicAuthListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.dto.PublicAuthListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.auth.param.PublicAuthQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.PublicMappingCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.dto.PublicMappingListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.dto.PublicMappingListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.param.PublicMappingBusinessUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.mapping.param.PublicMappingQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.PublicMenuCloudService;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.dto.PublicMenuListCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.dto.PublicMenuListItemCloudDto;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuCreateCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuDeleteCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuQueryCloudParam;
import com.youkeyi.ddy.cloud.common.api.basic.pub.menu.param.PublicMenuUpdateCloudParam;
import com.youkeyi.ddy.cloud.common.constant.YoukeyiDdyCloudBasicPublicConstant;
import com.youkeyi.ddy.cloud.common.context.YoukeyiSystemContext;
import com.youkeyi.ddy.cloud.common.enums.ResponseCodeEnum;
import com.youkeyi.ddy.cloud.common.response.ResponseContent;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * SystemMenuController
 *
 * @Author liuxiawang
 * @Date 2024/2/28 5:52 PM
 * @Location shenzhen.china
 */
@Service
public class SystemMenuController implements SystemMenuCloudService {

    @Autowired
    private PublicMenuCloudService publicMenuCloudService;
    @Autowired
    private PublicAuthCloudService publicAuthCloudService;
    @Autowired
    private PublicMappingCloudService publicMappingCloudService;

    @Override
    public SystemMenuListCloudDto list(SystemMenuListCloudParam param) {
        SystemMenuListCloudDto dto = new SystemMenuListCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicMenuQueryCloudParam menuQueryCloudParam = new PublicMenuQueryCloudParam();
        menuQueryCloudParam.setMenuPrimaryKeys(param.getMenuPrimaryKeys());
        menuQueryCloudParam.setNames(param.getNames());
        menuQueryCloudParam.setNameFuzzy(param.getNameFuzzy());
        menuQueryCloudParam.setCodes(param.getCodes());
        menuQueryCloudParam.setParentKeys(param.getParentKeys());
        menuQueryCloudParam.setPageSize(param.getPageSize());
        menuQueryCloudParam.setCurrentPage(param.getCurrentPage());
        PublicMenuListCloudDto menuDtos = publicMenuCloudService.query(menuQueryCloudParam);
        if (null != menuDtos && CollectionUtils.isNotEmpty(menuDtos.getRows())) {
            PublicMenuQueryCloudParam parentMenuQueryCloudParam = new PublicMenuQueryCloudParam();
            parentMenuQueryCloudParam.setMenuPrimaryKeys(menuDtos.getRows().stream().map(PublicMenuListItemCloudDto::getMenuPrimaryKey).collect(Collectors.toList()));
            PublicMenuListCloudDto parentMenuDtos = publicMenuCloudService.query(parentMenuQueryCloudParam);
            Map<String, String> parentMap = new HashMap<>();
            if (null != parentMenuDtos && CollectionUtils.isNotEmpty(parentMenuDtos.getRows())) {
                parentMap.putAll(parentMenuDtos.getRows().stream().collect(Collectors.toMap(PublicMenuListItemCloudDto::getMenuPrimaryKey, PublicMenuListItemCloudDto::getName, (k1, k2) -> k1)));
            }


            List<SystemMenuListItemCloudDto> items = new ArrayList<>();
            menuDtos.getRows().forEach(menu -> {
                SystemMenuListItemCloudDto item = new SystemMenuListItemCloudDto();
                item.setMenuPrimaryKey(menu.getMenuPrimaryKey());
                item.setName(menu.getName());
                item.setCode(menu.getCode());
                item.setUrl(menu.getUrl());
                item.setIcon(menu.getIcon());
                item.setParentKey(menu.getParentKey());
                item.setParentName(parentMap.get(item.getParentKey()));
                item.setRemark(menu.getRemark());
                item.setSort(menu.getSort());
                item.setIsHidden(menu.getIsHidden());
                item.setIsDisabled(menu.getIsDisabled());
                item.setIsDeleted(menu.getIsDeleted());
                item.setIsDeletedName(menu.getIsDeletedName());
                item.setCreateUserKey(menu.getCreateUserKey());
                item.setCreateTime(menu.getCreateTime());
                item.setCreateUserName(menu.getCreateUserName());
                items.add(item);
            });
            dto.setRows(items);
            dto.setTotal(menuDtos.getTotal());
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public SystemMenuDetailCloudDto detail(String menuPrimaryKey) {
        SystemMenuDetailCloudDto dto = new SystemMenuDetailCloudDto();
        String tenantKey = YoukeyiSystemContext.getTenantPrimaryKey();
        if (StringUtils.isBlank(tenantKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (StringUtils.isBlank(menuPrimaryKey)) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicMenuQueryCloudParam menuQueryCloudParam = new PublicMenuQueryCloudParam();
        menuQueryCloudParam.setMenuPrimaryKeys(Collections.singletonList(menuPrimaryKey));
        PublicMenuListCloudDto menus = publicMenuCloudService.query(menuQueryCloudParam);
        if (null != menus && CollectionUtils.isNotEmpty(menus.getRows())) {
            PublicMenuListItemCloudDto menu = menus.getRows().get(0);
            dto.setMenuPrimaryKey(menu.getMenuPrimaryKey());
            dto.setName(menu.getName());
            dto.setMenuCode(menu.getCode());
            dto.setUrl(menu.getUrl());
            dto.setIcon(menu.getIcon());
            dto.setParentKey(menu.getParentKey());
            dto.setAuthKeys(menu.getAuthKeys());
            dto.setRemark(menu.getRemark());
            dto.setSort(menu.getSort());
            dto.setIsHidden(menu.getIsHidden());
            dto.setIsDisabled(menu.getIsDisabled());
            dto.setIsDeleted(menu.getIsDeleted());
            dto.setIsDeletedName(menu.getIsDeletedName());
            dto.setCreateUserKey(menu.getCreateUserKey());
            dto.setCreateUserName(menu.getCreateUserName());
            dto.setCreateTime(menu.getCreateTime());
            dto.setUpdateUserKey(menu.getUpdateUserKey());
            dto.setUpdateUserName(menu.getUpdateUserName());
            dto.setUpdateTime(menu.getUpdateTime());
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public SystemMenuTreeCloudDto tree(SystemMenuTreeCloudParam param) {
        SystemMenuTreeCloudDto dto = new SystemMenuTreeCloudDto();
        String tenantKey = YoukeyiSystemContext.getTenantPrimaryKey();
        if (StringUtils.isBlank(tenantKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        PublicMenuQueryCloudParam menuQueryCloudParam = new PublicMenuQueryCloudParam();
        menuQueryCloudParam.setPath(param.getMenuPrimaryKey());
        PublicMenuListCloudDto menus = publicMenuCloudService.query(menuQueryCloudParam);
        if (null != menus && CollectionUtils.isNotEmpty(menus.getRows())) {
            List<String> authKeys = new ArrayList<>();
            menus.getRows().forEach(menu -> {
                if (CollectionUtils.isNotEmpty(menu.getAuthKeys())) {
                    authKeys.addAll(menu.getAuthKeys());
                }
            });
            Map<String, PublicAuthListItemCloudDto> authMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(authKeys)) {
                PublicAuthQueryCloudParam authQueryCloudParam = new PublicAuthQueryCloudParam();
                authQueryCloudParam.setAuthPrimaryKeys(authKeys);
                PublicAuthListCloudDto authDtos = publicAuthCloudService.query(authQueryCloudParam);
                if (null != authDtos && CollectionUtils.isNotEmpty(authDtos.getRows())) {
                    authMap.putAll(authDtos.getRows().stream().collect(Collectors.toMap(PublicAuthListItemCloudDto::getAuthPrimaryKey, Function.identity(), (k1, k2) -> k1)));
                }
            }

            List<SystemMenuTreeItemCloudDto> dtos = new ArrayList<>();
            menus.getRows().forEach(menu -> {
                SystemMenuTreeItemCloudDto dtoItem = new SystemMenuTreeItemCloudDto();
                dtoItem.setMenuPrimaryKey(menu.getMenuPrimaryKey());
                dtoItem.setName(menu.getName());
                dtoItem.setMenuCode(menu.getCode());
                dtoItem.setUrl(menu.getUrl());
                dtoItem.setIcon(menu.getIcon());
                dtoItem.setParentKey(menu.getParentKey());
                if (CollectionUtils.isNotEmpty(menu.getAuthKeys())) {
                    menu.getAuthKeys().forEach(authKey -> {
                        if (authMap.containsKey(authKey)) {
                            PublicAuthListItemCloudDto auth = authMap.get(authKey);
                            SystemAuthSimpleCloudDto authDto = new SystemAuthSimpleCloudDto();
                            authDto.setAuthPrimaryKey(authKey);
                            authDto.setName(auth.getName());
                            authDto.setCode(auth.getCode());
                            authDto.setUrl(auth.getUrl());
                            dtoItem.getAuths().add(authDto);
                        }
                    });
                }
                dtos.add(dtoItem);
            });

            List<SystemMenuTreeItemCloudDto> ddtos = new ArrayList<>();
            // 转树
            Map<String, List<SystemMenuTreeItemCloudDto>> menuByParentKeyMaps = dtos.stream().collect(Collectors.groupingBy(SystemMenuTreeItemCloudDto::getParentKey));
            dtos.forEach(item -> item.setChildren(menuByParentKeyMaps.get(item.getMenuPrimaryKey())));
            if (StringUtils.isNotBlank(param.getMenuPrimaryKey())) {
                dtos.forEach(item -> {
                    if (item.getMenuPrimaryKey().equals(param.getMenuPrimaryKey())) {
                        ddtos.add(item);
                    }
                });
                dto.setRows(ddtos);
            } else {
                dtos.forEach(item -> {
                    if (StringUtils.isBlank(item.getParentKey())) {
                        ddtos.add(item);
                    }
                });
                dto.setRows(ddtos);
            }
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent create(SystemMenuCreateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param
                || StringUtils.isBlank(param.getName())
                || StringUtils.isBlank(param.getCode())
        ) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicMenuCreateCloudParam menuCreateCloudParam = new PublicMenuCreateCloudParam();
        menuCreateCloudParam.setName(param.getName());
        menuCreateCloudParam.setCode(param.getCode());
        menuCreateCloudParam.setUrl(param.getUrl());
        menuCreateCloudParam.setIcon(param.getIcon());
        menuCreateCloudParam.setParentKey(param.getParentKey());
        menuCreateCloudParam.setAuthKeys(param.getAuthKeys());
        menuCreateCloudParam.setRemark(param.getRemark());
        menuCreateCloudParam.setSort(param.getSort());
        menuCreateCloudParam.setIsHidden(param.getIsHidden());
        menuCreateCloudParam.setIsDisabled(param.getIsDisabled());
        menuCreateCloudParam.setCreateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        menuCreateCloudParam.setCreateUserName(YoukeyiSystemContext.getUserName());
        return publicMenuCloudService.create(menuCreateCloudParam);
    }

    @Override
    public ResponseContent update(SystemMenuUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param
                || StringUtils.isBlank(param.getMenuPrimaryKey())
                || StringUtils.isBlank(param.getName())
                || StringUtils.isBlank(param.getCode())
                || StringUtils.isBlank(param.getUrl())
        ) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicMenuUpdateCloudParam menuUpdateCloudParam = new PublicMenuUpdateCloudParam();
        menuUpdateCloudParam.setMenuPrimaryKey(param.getMenuPrimaryKey());
        menuUpdateCloudParam.setName(param.getName());
        menuUpdateCloudParam.setCode(param.getCode());
        menuUpdateCloudParam.setUrl(param.getUrl());
        menuUpdateCloudParam.setIcon(param.getIcon());
        menuUpdateCloudParam.setParentKey(param.getParentKey());
        menuUpdateCloudParam.setAuthKeys(param.getAuthKeys());
        menuUpdateCloudParam.setRemark(param.getRemark());
        menuUpdateCloudParam.setSort(param.getSort());
        menuUpdateCloudParam.setIsHidden(param.getIsHidden());
        menuUpdateCloudParam.setIsDisabled(param.getIsDisabled());
        menuUpdateCloudParam.setUpdateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        menuUpdateCloudParam.setUpdateUserName(YoukeyiSystemContext.getUserName());
        return publicMenuCloudService.update(menuUpdateCloudParam);
    }

    @Override
    public ResponseContent delete(SystemMenuDeleteCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param || CollectionUtils.isEmpty(param.getMenuPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        PublicMenuDeleteCloudParam menuDeleteCloudParam = new PublicMenuDeleteCloudParam();
        menuDeleteCloudParam.setMenuPrimaryKeys(param.getMenuPrimaryKeys());
        menuDeleteCloudParam.setUpdateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        menuDeleteCloudParam.setUpdateUserName(YoukeyiSystemContext.getUserName());
        return publicMenuCloudService.delete(menuDeleteCloudParam);
    }


    @Override
    public SystemCorpMenuListCloudDto corpList(SystemCorpMenuListCloudParam param) {
        SystemCorpMenuListCloudDto dto = new SystemCorpMenuListCloudDto();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            dto.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return dto;
        }
        if (null == param || StringUtils.isBlank(param.getCorpPrimaryKey())) {
            dto.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return dto;
        }

        // 主体-菜单映射关系
        PublicMappingQueryCloudParam publicMappingQueryCloudParam = new PublicMappingQueryCloudParam();
        publicMappingQueryCloudParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_CORP_MENU.value());
        publicMappingQueryCloudParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        publicMappingQueryCloudParam.setKeys(Collections.singletonList(param.getCorpPrimaryKey()));
        PublicMappingListCloudDto publicMappingDtos = publicMappingCloudService.query(publicMappingQueryCloudParam);
        if (null != publicMappingDtos && CollectionUtils.isNotEmpty(publicMappingDtos.getRows())) {
            List<String> menuKeys = publicMappingDtos.getRows().stream().map(PublicMappingListItemCloudDto::getTargetKey).collect(Collectors.toList());
            PublicMenuQueryCloudParam menuQueryCloudParam = new PublicMenuQueryCloudParam();
            menuQueryCloudParam.setMenuPrimaryKeys(menuKeys);
            menuQueryCloudParam.setPageSize(param.getPageSize());
            menuQueryCloudParam.setCurrentPage(param.getCurrentPage());
            PublicMenuListCloudDto menuDtos = publicMenuCloudService.query(menuQueryCloudParam);
            if (null != menuDtos && CollectionUtils.isNotEmpty(menuDtos.getRows())) {
                PublicMenuQueryCloudParam parentMenuQueryCloudParam = new PublicMenuQueryCloudParam();
                parentMenuQueryCloudParam.setMenuPrimaryKeys(menuDtos.getRows().stream().map(PublicMenuListItemCloudDto::getMenuPrimaryKey).collect(Collectors.toList()));
                PublicMenuListCloudDto parentMenuDtos = publicMenuCloudService.query(parentMenuQueryCloudParam);
                Map<String, String> parentMap = new HashMap<>();
                if (null != parentMenuDtos && CollectionUtils.isNotEmpty(parentMenuDtos.getRows())) {
                    parentMap.putAll(parentMenuDtos.getRows().stream().collect(Collectors.toMap(PublicMenuListItemCloudDto::getMenuPrimaryKey, PublicMenuListItemCloudDto::getName, (k1, k2) -> k1)));
                }


                List<SystemCorpMenuListItemCloudDto> items = new ArrayList<>();
                menuDtos.getRows().forEach(menu -> {
                    SystemCorpMenuListItemCloudDto item = new SystemCorpMenuListItemCloudDto();
                    item.setCorpPrimaryKey(param.getCorpPrimaryKey());
                    item.setMenuPrimaryKey(menu.getMenuPrimaryKey());
                    item.setName(menu.getName());
                    item.setCode(menu.getCode());
                    item.setUrl(menu.getUrl());
                    item.setIcon(menu.getIcon());
                    item.setParentKey(menu.getParentKey());
                    item.setParentName(parentMap.get(item.getParentKey()));
                    item.setRemark(menu.getRemark());
                    item.setSort(menu.getSort());
                    item.setIsHidden(menu.getIsHidden());
                    items.add(item);
                });
                dto.setRows(items);
                dto.setTotal(menuDtos.getTotal());
            }
        }
        dto.setSuccessMessage(ResponseCodeEnum.SUCCESS.getMessage());
        return dto;
    }

    @Override
    public ResponseContent corpUpdate(SystemCorpMenuUpdateCloudParam param) {
        ResponseContent rc = new ResponseContent();
        String corpKey = YoukeyiSystemContext.getCorpPrimaryKey();
        if (StringUtils.isBlank(corpKey)) {
            rc.setErrorMessage(ResponseCodeEnum.TOKEN_INVALID.getMessage());
            return rc;
        }
        if (null == param || StringUtils.isBlank(param.getCorpPrimaryKey()) || CollectionUtils.isEmpty(param.getMenuPrimaryKeys())) {
            rc.setErrorMessage(ResponseCodeEnum.PARAMETER_ILLEGAL.getMessage());
            return rc;
        }

        // 主体-菜单映射关系
        PublicMappingBusinessUpdateCloudParam mappingBusinessUpdateCloudParam = new PublicMappingBusinessUpdateCloudParam();
        mappingBusinessUpdateCloudParam.setMappingType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_TYPE_CORP_MENU.value());
        mappingBusinessUpdateCloudParam.setKeyType(YoukeyiDdyCloudBasicPublicConstant.PUBLIC_MAPPING_KEY_TYPE_SOURCE.value());
        mappingBusinessUpdateCloudParam.setKeyTypeKey(param.getCorpPrimaryKey());
        mappingBusinessUpdateCloudParam.setChangeKeys(param.getMenuPrimaryKeys());
        mappingBusinessUpdateCloudParam.setCreateUserKey(YoukeyiSystemContext.getUserPrimaryKey());
        mappingBusinessUpdateCloudParam.setCreateUserName(YoukeyiSystemContext.getUserName());
        return publicMappingCloudService.businessUpdate(mappingBusinessUpdateCloudParam);
    }
}
